package demo.game.chess.client.ui;

import java.util.HashMap;
import java.util.Map;

import com.allen_sauer.gwt.log.client.Log;

import demo.game.chess.client.ui.AbstractColorTheme.EnumColorStyle;
import demo.game.chess.common.ChessCell;
import demo.game.chess.common.ChessMove;
import demo.game.chess.common.MoveException;

public class ChessMoveValidatorUI {

	//	private ChessPieceUI highLightedSelection;

	private ChessPieceUI selectedPieceUI;

	private ChessCellUI originCellUI;

	private final Map<ChessCell, ChessMove> validMoveMap = new HashMap<ChessCell, ChessMove>();

	private final Map<ChessCell, MoveException> moveExceptionMap = new HashMap<ChessCell, MoveException>();

	private final AbstractChessUI mainUI;

	private boolean isDndMode = false;

	public ChessMoveValidatorUI(final AbstractChessUI mainUI) {
		super();
		this.mainUI = mainUI;
	}

	public boolean canDropPieceAt(final ChessCellUI cellUI) {

		if (this.selectedPieceUI != null) {
			ChessMove move = getValidMoveForCell(cellUI);
			if (null != move) {
				return true;
			}
		}
		return false;
	}

	private void clearSelection() {

		this.selectedPieceUI = null;
		this.originCellUI = null;

		this.validMoveMap.clear();
		this.moveExceptionMap.clear();
	}

	private ChessMove getValidMoveForCell(final ChessCellUI cellUI) {
		ChessMove move = null;
		if (!this.validMoveMap.containsKey(cellUI.getCell())) {

			try {
				move = this.mainUI.getManager().getCurrentBoard()
						.createValidMove(this.originCellUI.getCell(),
								cellUI.getCell());
			} catch (MoveException ex) {
				this.moveExceptionMap.put(cellUI.getCell(), ex);

			}

			// Log.debug("onMouseIn " + cellUI + ": valid move " + move);
			this.validMoveMap.put(cellUI.getCell(), move);

		} else {
			move = this.validMoveMap.get(cellUI.getCell());
		}

		return move;

	}

	private void heighlightAllValidTargets() {
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				ChessCellUI cellUI = this.mainUI.getBoard().getCellUI(i, j);
				heightlightIfValidTarget(cellUI);
			}
		}
	}

	private void heightlightIfValidTarget(final ChessCellUI cellUI) {
		ChessMove move = getValidMoveForCell(cellUI);

		if (null != move) {
			cellUI
					.addHighlightStyle(EnumColorStyle.chessCellSelectedMoveTarget);
			Log.debug(getClass() + ": heighlight " + cellUI
					+ " for valid move: " + move);
		} else {
			cellUI
					.removeHighlightStyle(EnumColorStyle.chessCellSelectedMoveTarget);

		}

	}

	public boolean isDndMode() {
		return this.isDndMode;
	}

	public void onDropPieceAt(final ChessCellUI cellUI) {
		try {

			//			if (!this.isDndMode) {
			//				selectPiece(this.highLightedSelection);
			//			}
			//			Log.debug(getClass() + " onDropPieceAt piece="
			//					+ this.selectedPieceUI + " target=" + cellUI);
			if (canDropPieceAt(cellUI)) {
				ChessMove move = this.validMoveMap.get(cellUI.getCell());
				Log.debug(getClass() + " onDropPieceAt - confirmMove "

				+ " piece=" + this.selectedPieceUI + " move=" + move);
				this.mainUI.confirmMove(move);

				clearSelection();
				//this.highLightedSelection = null;
			}

		} catch (Throwable e) {
			Log.error("error", e);
		}
	}

	public void onMouseIn(final ChessCellUI cellUI) {
		try {

			if (this.selectedPieceUI != null) {

				if (null != this.moveExceptionMap.get(cellUI.getCell())) {
					MoveException warning = this.moveExceptionMap.get(cellUI
							.getCell());
					this.mainUI.showInfoWarning(warning);
				} else {
					this.mainUI.clearWarning();
				}

			}

		} catch (Throwable e) {
			Log.error("error", e);
		}
	}

	public void onMouseOut(final ChessCellUI cellUI) {
		//Log.debug("ChessMoveValidator: onMouseOut " + cellUI);
		this.mainUI.clearWarning();

	}

	public void selectPiece(final ChessPieceUI pieceUI) {
		try {

			if (pieceUI != this.selectedPieceUI
					&& this.mainUI.isPlayerAllowed(pieceUI.getPiece()
							.getColor())) {

				Log.debug(getClass() + " selectPiece " + pieceUI);
				if (null != this.originCellUI) {
					this.originCellUI
							.removeHighlightStyle(EnumColorStyle.chessCellSelectedMoveOrigin);
				}

				this.selectedPieceUI = pieceUI;
				this.originCellUI = pieceUI.getCellUI();
				this.originCellUI
						.addHighlightStyle(EnumColorStyle.chessCellSelectedMoveOrigin);

				this.validMoveMap.clear();
				this.moveExceptionMap.clear();

				heighlightAllValidTargets();
			}
		} catch (Throwable e) {
			Log.error("error", e);
		}
	}

	public void setDndMode(final boolean isDndMode) {
		//Log.debug("ChessMoveValidator: dndMode=" + isDndMode);
		this.isDndMode = isDndMode;
	}

}
